package cn.datawin.bms.modules.customer.service.impl;

import cn.datawin.bms.customer.bo.CstmCustomerBo;
import cn.datawin.bms.customer.bo.CstmCustomerConfigBo;
import cn.datawin.bms.customer.entity.CstmCorporateEntity;
import cn.datawin.bms.customer.entity.CstmCustomerCmppConfigEntity;
import cn.datawin.bms.customer.entity.CstmCustomerEntity;
import cn.datawin.bms.customer.redis.CstmCustomerCmppRedisDto;
import cn.datawin.bms.customer.vo.CstmCustomerConfigVo;
import cn.datawin.bms.customer.vo.CstmCustomerVo;
import cn.datawin.bms.modules.customer.mapper.CstmCustomerMapper;
import cn.datawin.bms.modules.customer.service.CstmCorporateService;
import cn.datawin.bms.modules.customer.service.CstmCustomerCmppConfigService;
import cn.datawin.bms.modules.customer.service.CstmCustomerService;
import cn.datawin.common.core.util.RedisUtils;
import cn.datawin.constant.RedisPattern;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

import static cn.datawin.constant.RedisPattern.CSTM_CUSTOMER_START;

/**
 * 下游客户
 *
 * @author datawin-sms
 * @date 2025-06-17 14:46:46
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class CstmCustomerServiceImpl extends ServiceImpl<CstmCustomerMapper, CstmCustomerEntity> implements CstmCustomerService {

	private final CstmCustomerCmppConfigService cstmCustomerCmppConfigService;
	private final CstmCorporateService cstmCorporateService;

	@Override
	public Page<CstmCustomerVo> customPage(Page<CstmCustomerEntity> page, CstmCustomerEntity query) {

		//分页查询数据
		LambdaQueryWrapper<CstmCustomerEntity> wrapper = Wrappers.lambdaQuery();
		wrapper.like(StrUtil.isNotBlank(query.getName()), CstmCustomerEntity::getName, query.getName());
		wrapper.eq(StrUtil.isNotBlank(query.getCode()), CstmCustomerEntity::getCode, query.getCode());
		wrapper.eq(Objects.nonNull(query.getStatus()), CstmCustomerEntity::getStatus, query.getStatus());
		wrapper.eq(StrUtil.isNotBlank(query.getMethod()), CstmCustomerEntity::getMethod, query.getMethod());
		Page<CstmCustomerEntity> page1 = this.page(page, wrapper);

		//关联查询必要的数据
		Page<CstmCustomerVo> customPage = new Page<>();
		customPage.setCurrent(page1.getCurrent());
		customPage.setSize(page1.getSize());
		customPage.setTotal(page1.getTotal());
		List<CstmCustomerEntity> records = page1.getRecords();
		if (CollUtil.isNotEmpty(records)) {
			List<Long> corporateIdList = records.stream().map(CstmCustomerEntity::getCorporateId).distinct().toList();
			List<CstmCorporateEntity> corporateEntities = cstmCorporateService.getByIds(corporateIdList);
			Map<Long, String> cstmCorporateNameMap = corporateEntities.stream().collect(Collectors.toMap(CstmCorporateEntity::getId, CstmCorporateEntity::getName));
			List<CstmCustomerVo> voList = BeanUtil.copyToList(records, CstmCustomerVo.class);
			for (CstmCustomerVo cstmCustomerVo : voList) {
				cstmCustomerVo.setCorporateName(cstmCorporateNameMap.get(cstmCustomerVo.getCorporateId()));
			}
			customPage.setRecords(voList);

		}
		return customPage;
	}

	@Override
	public CstmCustomerEntity newCstmCustomer() {
		if (!RedisUtils.hasKey(CSTM_CUSTOMER_START)) {
			RedisUtils.incr(CSTM_CUSTOMER_START, 200000L);
		}
		long account = RedisUtils.incr(CSTM_CUSTOMER_START, 1L);
		CstmCustomerEntity cstmCustomerEntity = new CstmCustomerEntity();
		cstmCustomerEntity.setCode(account + "");
		cstmCustomerEntity.setStatus(0);

		return cstmCustomerEntity;
	}

	@Override
	public boolean insertByBo(CstmCustomerBo bo) {
		log.info("CstmCustomerService---insertByBo---bo:{}", bo.toString());
		//hutool 拷贝属性
		CstmCustomerEntity cstmCustomerEntity = BeanUtil.copyProperties(bo, CstmCustomerEntity.class);
		//通道选择策略默认选择价格优先
		cstmCustomerEntity.setChannelSelectStrategy("price");
		boolean save = this.save(cstmCustomerEntity);
		if (save) {
			//获取method
			String method = bo.getMethod();
			//获取methodParams
//			String methodParams = bo.getMethodParams();
//			log.info("CstmCustomerService---insertByBo---method:{} methodParams:{}",method,methodParams);
			if (method.equals("cmpp")) {
				CstmCustomerCmppConfigEntity config = new CstmCustomerCmppConfigEntity();
				config.setAccount(cstmCustomerEntity.getCode());
				//随机生成一个字母数字组合8位
				config.setPassword(RandomUtil.randomString(8));
				config.setCustomerId(cstmCustomerEntity.getId());
				cstmCustomerCmppConfigService.save(config);
			}
			dataToCache(cstmCustomerEntity.getId());
		}
		return save;
	}

	@Override
	public boolean updateByBo(CstmCustomerBo bo) {
		CstmCustomerEntity cstmCustomerEntity = BeanUtil.copyProperties(bo, CstmCustomerEntity.class);
		boolean b = this.updateById(cstmCustomerEntity);

		dataToCache(cstmCustomerEntity.getId());
		return b;
	}

	@Override
	public CstmCustomerVo getInfo(Long id) {
		CstmCustomerEntity customer = this.getById(id);
		Long corporateId = customer.getCorporateId();
		CstmCorporateEntity corporateEntity = cstmCorporateService.getById(corporateId);
		CstmCustomerVo cstmCustomerVo = BeanUtil.copyProperties(customer, CstmCustomerVo.class);
		cstmCustomerVo.setCorporateName(corporateEntity.getName());
		return cstmCustomerVo;
	}


	/**
	 * 更新状态
	 *
	 * @param customerId
	 * @param status
	 * @return
	 */
	@Override
	public boolean updateStatus(Long customerId, Integer status) {
		//更新状态
		CstmCustomerEntity customer = new CstmCustomerEntity();
		customer.setId(customerId);
		customer.setStatus(status);
		boolean b = this.updateById(customer);
		dataToCache(customerId);
		return b;
	}


	@Override
	public boolean removeBatch(Long[] ids) {
		List<CstmCustomerEntity> cstmCustomerEntities = this.baseMapper.selectBatchIds(Arrays.asList(ids));
		for (CstmCustomerEntity cstmCustomerEntity : cstmCustomerEntities) {
			String rKey = String.format(RedisPattern.CSTM_CUSTOMER_CMPP_CACHE, cstmCustomerEntity.getCode());
			log.info("删除用户cmpp信息缓存---{}", rKey);
			RedisUtils.del(rKey);
		}
		return this.removeBatchByIds(CollUtil.toList(ids));
	}

	@Override
	public CstmCustomerConfigVo getConfigByCustomerId(Long customerId) {
		CstmCustomerEntity customer = this.getById(customerId);
		String method = customer.getMethod();
		if (method.equals("cmpp")) {
			//查询cmpp配置
			LambdaQueryWrapper<CstmCustomerCmppConfigEntity> wrapper = Wrappers.lambdaQuery();
			wrapper.eq(CstmCustomerCmppConfigEntity::getCustomerId, customer.getId());
			CstmCustomerCmppConfigEntity config = cstmCustomerCmppConfigService.getOne(wrapper);
			if (Objects.nonNull(config)) {
				CstmCustomerConfigVo cstmCustomerConfigVo = new CstmCustomerConfigVo();
				cstmCustomerConfigVo.setCustomerId(customerId);
				cstmCustomerConfigVo.setMethod("cmpp");
				Map<String, Object> methodParams = new HashMap<>();
				methodParams.put("account", config.getAccount());
				methodParams.put("password", config.getPassword());
				methodParams.put("spCode", config.getSpCode());
				methodParams.put("ips", config.getIps());
				methodParams.put("serverInfoId", config.getServerInfoId());
				methodParams.put("connections", config.getConnections());
				methodParams.put("acceptRate", config.getAcceptRate());
				methodParams.put("needProviderDest", config.getNeedProviderDest());
				cstmCustomerConfigVo.setMethodParams(methodParams);
				return cstmCustomerConfigVo;
			}
		}
		if (method.equals("http")) {
			//查询http配置
//			LambdaQueryWrapper<CstmCustomerCmppConfigEntity> wrapper = Wrappers.lambdaQuery();
//			wrapper.eq(CstmCustomerCmppConfigEntity::getCustomerId,customer);
//			CstmCustomerCmppConfigEntity config = cstmCustomerCmppConfigService.getOne(wrapper);
//			if(Objects.nonNull(config)){
//				return JSON.toJSONString(config);
//			}
		}
		return null;
	}

	@Override
	public boolean updateConfigByCustomerId(CstmCustomerConfigBo bo) {

		//获取method
		String method = bo.getMethod();
		Long customerId = bo.getCustomerId();
		//获取methodParams
		Map<String, Object> methodParams = bo.getMethodParams();
		log.info("CstmCustomerService---insertByBo---method:{} methodParams:{}", method, methodParams);
		if (method.equals("cmpp")) {
			CstmCustomerCmppConfigEntity config = JSON.parseObject(JSON.toJSONString(methodParams), CstmCustomerCmppConfigEntity.class);
			config.setCustomerId(customerId);
			cstmCustomerCmppConfigService.updateByCustomerId(customerId, config);
			//更新缓存
			dataToCache(customerId);
		}

		return false;
	}

	/**
	 * 数据同步到缓存
	 *
	 * @param customerId 客户id
	 */
	void dataToCache(Long customerId) {
		CstmCustomerEntity cstmCustomerEntity = this.baseMapper.selectById(customerId);

		if (Objects.nonNull(cstmCustomerEntity)) {

			LambdaQueryWrapper<CstmCustomerCmppConfigEntity> wrapper = Wrappers.lambdaQuery();
			wrapper.eq(CstmCustomerCmppConfigEntity::getCustomerId, customerId);
			String method = cstmCustomerEntity.getMethod();
			if (method.equals("cmpp")) {
				//查询cmpp配置
				CstmCustomerCmppConfigEntity config = cstmCustomerCmppConfigService.getOne(wrapper);
				if (Objects.nonNull(config)) {
					//构造一个CstmCustomerCmppRedisDto对象存入redis
					CstmCustomerCmppRedisDto redisDto = new CstmCustomerCmppRedisDto();
					redisDto.setStatus(cstmCustomerEntity.getStatus());

					redisDto.setCustomerId(customerId);
					redisDto.setCustomerCode(config.getAccount());
					redisDto.setPassword(config.getPassword());
					redisDto.setSpCode(config.getSpCode());
					redisDto.setIps(redisDto.getIps());
					redisDto.setSpCode(config.getSpCode());
					redisDto.setConnections(config.getConnections());
					redisDto.setAcceptRate(config.getAcceptRate());
					redisDto.setNeedProviderDest(config.getNeedProviderDest());
					String rKey = String.format(RedisPattern.CSTM_CUSTOMER_CMPP_CACHE, cstmCustomerEntity.getCode());
					RedisUtils.set(rKey, redisDto);
					CstmCustomerCmppRedisDto redisDto1 = RedisUtils.get(rKey);
					log.info("设置用户cmpp信息到缓存中---{}---{}", rKey, JSON.toJSONString(redisDto1));
				}
			}

		}

	}

}
